﻿using Station.Inspect;
using Station.Inspect.SuaModel;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Vision.Common;

namespace Station.Common.Rejudgment
{
    /// <summary>
    /// 算子检测元件
    /// </summary>
    public class ErrComponent
    {
        public string facename;

        /// <summary>
        /// 运动位置,像素坐标
        /// </summary>
        public Rectangle Position { get; set; } = new Rectangle();
        /// <summary>
        /// 运动位置，物理坐标
        /// </summary>
        public RectangleF RealPosition { get; set; }

        /// <summary>
        /// 区域角度
        /// </summary>
        public float Angle { get; set; }
        public PointF CenterPoint
        {
            get
            {
                Matrix matrix = new Matrix();
                matrix.Translate(RealPosition.X, RealPosition.Y);
                matrix.Rotate(Angle);
                var pts = new PointF[1];
                pts[0] = new PointF(RealPosition.Width / 2, RealPosition.Height / 2);
                matrix.TransformPoints(pts);
                return pts[0];
            }
        }
        public NodeLib Lib { get; set; }
        public int MarkID { get; set; }
        /// <summary>
        /// 图片
        /// </summary>
        public Bitmap Image { get; set; }

        /// <summary>
        /// 镜头中心
        /// </summary>
        Point CameraCenter { get; set; }
        /// <summary>
        /// 镜头图片
        /// </summary>
        public Bitmap CameraImage { get; set; }
        /// <summary>
        /// 检测Cell
        /// </summary>
        public List<ErrCell> ErrCells { get; set; } = new List<ErrCell>();

        /// <summary>
        /// 报点列表
        /// </summary>
        public List<RectErr> RectErrs { get; set; } = new List<RectErr>();
        public CellStatus Status { get; set; } = CellStatus.PASS;
        public CellStatus GetState()
        {
            if (ErrCells.Count > 0)
            {
                bool bOK = false;
                foreach (var cell in ErrCells)
                {
                    if (cell.Status == CellStatus.NG)
                        return CellStatus.NG;
                    else if (cell.Status == CellStatus.OK)
                        bOK = true;
                }
                if (bOK)
                    return CellStatus.OK;
                else
                    return CellStatus.PASS;
            }
            else
                return Status;
        }
        public bool SetImage(Bitmap cameraImage, Point cameraCenter)
        {
            CameraImage = cameraImage;
            CameraCenter = cameraCenter;

            RectangleF rt = GetRect();
            RectangleF rect = new RectangleF(rt.Left - cameraCenter.X + 4096 / 2, rt.Top - cameraCenter.Y + 3000 / 2, rt.Width, rt.Height);
            Image = (Bitmap)CameraImage.Clone(rect, PixelFormat.Format24bppRgb);
            if (Angle > 1.192092896e-07F && Image != null)
            {
                int w = Position.Width;
                int h = Position.Height;
                Bitmap tempImg = new Bitmap(w, h, PixelFormat.Format24bppRgb);
                Graphics g = Graphics.FromImage(tempImg);
                g.TranslateTransform(w / 2.0f, h / 2.0f);
                g.RotateTransform(-Angle);
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
                g.DrawImage(Image, -Image.Width / 2, -Image.Height / 2);
                Image = tempImg;
            }
            if (Lib != null)
            {
                if (Image != null && Lib.ModelMark != null && ErrCells.Count > 0)
                {
                    string logStr = $"SetImage,PCS{MarkID}-lib{Lib.ID}:";
                    Matrix matrix = new Matrix();
                    matrix.Translate(Position.Left, Position.Top);
                    matrix.Rotate(Angle);
                    List<PointL> locs = Lib.ModelMark.Find(Image, Lib.ModelMinScore, ErrCells.Count);
                    logStr += $"count={locs.Count}/{ErrCells.Count}\r\n";
                    PointF[] pts = new PointF[1];
                    foreach (var loc in locs)
                    {
                        logStr += $"loc=({loc.X},{loc.Y},{loc.Angle}),";
                        foreach (var p in ErrCells)
                        {
                            float dx = loc.X - (p.Rect.Left + p.Rect.Right) / 2.0f;
                            float dy = loc.Y - (p.Rect.Top + p.Rect.Bottom) / 2.0f;
                            if (Math.Abs(dx) <= Lib.ModelRange && Math.Abs(dy) <= Lib.ModelRange)
                            {
                                logStr += $"id={p.ID},dx={dx},dy={dy},range={Lib.ModelRange},rectOld={p.Rect.ToString()},";
                                int l = (int)dx + p.Rect.Location.X;
                                int t = (int)dy + p.Rect.Location.Y;
                                p.Rect = new Rectangle(l, t, p.Rect.Width, p.Rect.Height);
                                logStr += $"rectNew={p.Rect.ToString()},posOld={p.Pos.ToString()},RealPosOld={p.RealPos.ToString()},";
                                pts[0] = new PointF((p.Rect.Left + p.Rect.Right) / 2.0f, (p.Rect.Top + p.Rect.Bottom) / 2.0f);
                                matrix.TransformPoints(pts);
                                p.Pos = pts[0];
                                p.RealPos = StaInspect.Instance.Rbt.P2TPByOrig(p.Pos).ToPointF();
                                logStr += $"pos={p.Pos.ToString()},{p.RealPos.ToString()}\r\n";
                                break;
                            }
                        }
                        if (logStr[logStr.Length - 1] != '\n')
                            logStr += "\r\n";
                    }

                    Log.Instance.Debug(logStr);

                }
            }
            return Image != null;
        }

        public RectangleF GetRect()
        {
            PointF[] point = new PointF[]
            {
                new PointF(Position.Left,Position.Bottom),
                new PointF(Position.Right,Position.Top),
                new PointF(Position.Right,Position.Bottom)
            };
            Matrix matrix = new Matrix();
            matrix.RotateAt(Angle, new PointF(Position.X, Position.Y), MatrixOrder.Append);
            matrix.TransformPoints(point);
            float l = Position.X;
            float r = Position.X;
            float t = Position.Y;
            float b = Position.Y;
            for (int i = 0; i < 3; i++)
            {
                if (l > point[i].X)
                    l = point[i].X;
                if (r < point[i].X)
                    r = point[i].X;
                if (t > point[i].Y)
                    t = point[i].Y;
                if (b < point[i].Y)
                    b = point[i].Y;
            }
            RectangleF rect = new RectangleF(l, t, (r - l), (b - t));
            return rect;

        }

        public bool Save(string path)
        {
            return true;
        }
    }
}
